home *** CD-ROM | disk | FTP | other *** search
/ Aminet 45 / Aminet 45 (2001)(GTI - Schatztruhe)[!][Oct 2001].iso / Aminet / util / misc / ReportPlus.lha / reportplus / source / f10.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-08-20  |  34.2 KB  |  1,122 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <intuition/gadgetclass.h>
  5. #include <libraries/gadtools.h>
  6. #include <dos/dos.h>
  7. #include <dos/dostags.h>
  8. #include <dos/dosextens.h>
  9. #include <dos/exall.h>
  10. #include <dos/datetime.h>
  11. #include <graphics/gfx.h>
  12.  
  13. #include <clib/alib_protos.h>
  14. #include <clib/intuition_protos.h>
  15. #include <clib/graphics_protos.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/gadtools_protos.h>
  18. #include <clib/exec_protos.h>
  19.  
  20. #include <ctype.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "rp.h"
  24. #include "files.h"
  25.  
  26. #include <reaction/reaction.h>
  27. #include <gadgets/listbrowser.h>
  28. #include <pragmas/listbrowser_pragmas.h>
  29.  
  30. #define GID_10_LB1 0
  31. #define GIDS_10    GID_10_LB1
  32.  
  33. MODULE void updatefiles(void);
  34. MODULE void stage1(void);
  35. MODULE void files_work(void);                                 // for stage1()
  36. MODULE void stage2(void);
  37. MODULE ABOOL __inline quickcomp(STRPTR first, STRPTR second); // for stage2()
  38. MODULE void dobuffer(ABOOL item, ULONG whichpen);             // for stage2()
  39. MODULE void stage3(void);
  40.  
  41. IMPORT ABOOL                fillwindows;
  42. IMPORT TEXT                 IOBuffer[LONGESTFIELD + 1],
  43.                             aslresult[MEDFIELD + 1];
  44. IMPORT SBYTE                page;
  45. IMPORT ULONG                wbval;
  46. IMPORT struct SharedStruct  shared;
  47. IMPORT struct Screen*       ScreenPtr;
  48. IMPORT struct Library*      ListBrowserBase;
  49. IMPORT struct ExAllData*    EADataPtr;
  50. IMPORT struct VisualInfo*   VisualInfoPtr;
  51. IMPORT struct NewGadget     Gadget;
  52. IMPORT struct List          EmptyList;
  53.  
  54. MODULE struct Gadget       *gadgets[GIDS_10 + 1];
  55. MODULE struct List          DirList, FileList;
  56. MODULE struct List          ResultList;
  57. MODULE ABOOL                ResultNodes = FALSE,
  58.                             stop;
  59. MODULE struct
  60. {   ABOOL show[8];
  61.     TEXT  showlabel[8][17 + 1];
  62.     TEXT  path[VLONGFIELD + 1];
  63.     ULONG entries;
  64.     UWORD osversion;
  65. } files =
  66. {   TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,
  67.     "Very important",
  68.     "Important",
  69.     "Semi-important",
  70.     "Unimportant",
  71.     "Obsolete",
  72.     "3rd-party",
  73.     "Missing normal",
  74.     "Missing optional",
  75.     "", 0
  76. };
  77. MODULE  BPTR           LogFileHandle       = NULL;
  78. MODULE  TEXT           stringholder1[VLONGFIELD + 1],
  79.                        stringholder2[VLONGFIELD + 1],
  80.                        lockstring[VLONGFIELD + 1];
  81. MODULE  struct Gadget *CY101_OSVersion     = NULL,
  82.                       *TE101_Status        = NULL,
  83.                       *TE101_ShowText      = NULL,
  84.                       *CB101_Show[8] =
  85.                       {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
  86.  
  87. #define OSVERSIONS 5 // counting from 0
  88. MODULE  STRPTR OSOptions[OSVERSIONS + 2] =
  89. {   "OS3.1",
  90.     "OS3.5",
  91.     "OS3.5 & Boing Bag(s)",
  92.     "OS3.9",
  93.     "OS3.9 & Genesis Update",
  94.     "OS3.9 & Boing Bag 1",
  95.     NULL
  96. };
  97. MODULE struct
  98. {   ULONG red, green, blue, pennumber;
  99. } penn[8] =
  100. {     {0xFFFFFFFF, 0x22222222, 0x22222222, -1}, // red
  101.       {0xFFFFFFFF, 0x88888888, 0x00000000, -1}, // orange
  102.       {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, -1}, // yellow
  103.       {0x55555555, 0xFFFFFFFF, 0x55555555, -1}, // green
  104.       {0x55555555, 0x55555555, 0xFFFFFFFF, -1}, // blue (obsolete)
  105.       {0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, -1}, // cyan (3rd-party)
  106.       {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -1}, // white (missing normal)
  107.       {0xFFFFFFFF, 0x99999999, 0x99999999, -1}  // pink (missing optional)
  108. };
  109.  
  110. // from rp.c
  111. IMPORT SBYTE               page;
  112. IMPORT struct Gadget      *BU99_Right,
  113.                           *ST99_Output,
  114.                           *BU99_OutputASL,
  115.                           *BU99_Update,
  116.                           *BU99_Stop,
  117.                           *CB99_Log,
  118.                           *PrevGadPtr;
  119. IMPORT struct Window*      MainWindowPtr;
  120. IMPORT TEXT                weekdaystring[LEN_DATSTRING],
  121.                            datestring[LEN_DATSTRING],
  122.                            timestring[LEN_DATSTRING];
  123.  
  124. AGLOBAL void files1(void)
  125. {   ULONG i;
  126.  
  127.     verynewwindow
  128.     (   FILES1WIDTH, FILES1HEIGHT,
  129.         "Report+: System File Report",
  130.         BUTTONIDCMP | STRINGIDCMP | CYCLEIDCMP | CHECKBOXIDCMP
  131.     );
  132.     if (fillwindows)
  133.     {   SetAPen(MainWindowPtr->RPort, 0);
  134.         RectFill(MainWindowPtr->RPort, 446, 20, 446 + 72, 20 + 12); // TE101_Status
  135.     }
  136.  
  137.     if (!(gadgets[GID_10_LB1] = (struct Gadget *) NewObject
  138.     (   LISTBROWSER_GetClass(),   NULL,
  139.         GA_ID,                    GID_10_LB1,
  140.         GA_Left,                  10,
  141.         GA_Top,                   144,
  142.         GA_Width,                 FILES1WIDTH - 20,
  143.         GA_Height,                84,
  144.         GA_ReadOnly,              TRUE,
  145.         GA_TextAttr,              Gadget.ng_TextAttr,
  146.         LISTBROWSER_ScrollRaster, TRUE,
  147.         LISTBROWSER_Labels,       (ULONG) &EmptyList,
  148.         TAG_END
  149.     )))
  150.     {   rq("Can't create ReAction gadgets!");
  151.     }
  152.     AddGList(MainWindowPtr, gadgets[GID_10_LB1], -1, -1, NULL);
  153.     RefreshGList(gadgets[GID_10_LB1], MainWindowPtr, NULL, -1);
  154.  
  155.     setgadget(244, 119, 244, 12, "AmigaOS _Version", PLACETEXT_ABOVE);
  156.     CY101_OSVersion = PrevGadPtr = (struct Gadget *) CreateGadget
  157.     (   CYCLE_KIND,
  158.         PrevGadPtr,
  159.         &Gadget,
  160.         GTCY_Labels, OSOptions,
  161.         GTCY_Active, files.osversion,
  162.         GT_Underscore, '_',
  163.         TAG_DONE
  164.     );
  165.  
  166.     // show
  167.     setgadget(10, 35, 40, 0, "Show:", PLACETEXT_ABOVE);
  168.     TE101_ShowText = PrevGadPtr = (struct Gadget *) CreateGadget
  169.     (   TEXT_KIND,
  170.         PrevGadPtr,
  171.         &Gadget,
  172.         TAG_DONE
  173.     );
  174.  
  175.     SetDrMd(MainWindowPtr->RPort, JAM2);
  176.     SetAPen(MainWindowPtr->RPort, BLACK);
  177.     for (i = 0; i <= 7; i++)
  178.     {   setgadget(16, 35 + (i * 12), 0, 0, NULL, PLACETEXT_RIGHT);
  179.         Move(MainWindowPtr->RPort, 49, 43 + (i * 12));
  180.         SetBPen(MainWindowPtr->RPort, penn[i].pennumber);
  181.         Text(MainWindowPtr->RPort, files.showlabel[i], strlen(files.showlabel[i]));
  182.         CB101_Show[i] = PrevGadPtr = (struct Gadget *) CreateGadget
  183.         (   CHECKBOX_KIND,
  184.             PrevGadPtr,
  185.             &Gadget,
  186.             GTCB_Checked, files.show[i],
  187.             GT_Underscore, '_',
  188.             TAG_DONE
  189.         );
  190.     }
  191.     SetDrMd(MainWindowPtr->RPort, JAM1);
  192.     Move(MainWindowPtr->RPort, 49 + (8 * 1),  43);
  193.     Text(MainWindowPtr->RPort, "_", 1);
  194.     Move(MainWindowPtr->RPort, 49 + (8 * 0),  55);
  195.     Text(MainWindowPtr->RPort, "_", 1);
  196.     Move(MainWindowPtr->RPort, 49 + (8 * 0),  67);
  197.     Text(MainWindowPtr->RPort, "_", 1);
  198.     Move(MainWindowPtr->RPort, 49 + (8 * 1),  79);
  199.     Text(MainWindowPtr->RPort, "_", 1);
  200.     Move(MainWindowPtr->RPort, 49 + (8 * 1),  91);
  201.     Text(MainWindowPtr->RPort, "_", 1);
  202.     Move(MainWindowPtr->RPort, 49 + (8 * 0), 103);
  203.     Text(MainWindowPtr->RPort, "_", 1);
  204.     Move(MainWindowPtr->RPort, 49 + (8 * 6), 115);
  205.     Text(MainWindowPtr->RPort, "_", 1);
  206.     Move(MainWindowPtr->RPort, 49 + (8 * 9), 127);
  207.     Text(MainWindowPtr->RPort, "_", 1);
  208.  
  209.     /* update */
  210.     setgadget(244, 20, 60, 12, "_Update", NULL);
  211.     BU99_Update = PrevGadPtr = (struct Gadget *) CreateGadget
  212.     (   BUTTON_KIND,
  213.         PrevGadPtr,
  214.         &Gadget,
  215.         GT_Underscore, '_',
  216.         TAG_DONE
  217.     );
  218.     /* stop */
  219.     setgadget(304, 20, 60, 12, "Stop", NULL);
  220.     BU99_Stop = PrevGadPtr = (struct Gadget *) CreateGadget
  221.     (   BUTTON_KIND,
  222.         PrevGadPtr,
  223.         &Gadget,
  224.         GA_Disabled, TRUE,
  225.         TAG_DONE
  226.     );
  227.  
  228.     if (wbval >= 44)
  229.         shared.log = FALSE;
  230.     else shared.log = TRUE;
  231.     // log to file?
  232.     setgadget(244, 45, 0, 0, "_Log to file?", PLACETEXT_RIGHT);
  233.     CB99_Log = PrevGadPtr = (struct Gadget *) CreateGadget
  234.     (   CHECKBOX_KIND,
  235.         PrevGadPtr,
  236.         &Gadget,
  237.         GTCB_Checked, shared.log,
  238.         GT_Underscore, '_',
  239.         TAG_DONE
  240.     );
  241.  
  242.     /* output */
  243.     if (!(shared.output[0]))
  244.         strcpy(shared.output, "RAM:Report.txt");
  245.     setgadget(244, 72, 244, 12, "_Output pathname:", PLACETEXT_ABOVE);
  246.     ST99_Output = PrevGadPtr = (struct Gadget *) CreateGadget
  247.     (   STRING_KIND,
  248.         PrevGadPtr,
  249.         &Gadget,
  250.         GTST_String, &(shared.output),
  251.         GTST_MaxChars, LONGFIELD,
  252.         GA_TabCycle, TRUE,
  253.         GT_Underscore, '_',
  254.         TAG_DONE
  255.     );
  256.     /* output... */
  257.     setgadget(490, 72, 28, 12, "_...", NULL);
  258.     BU99_OutputASL = PrevGadPtr = (struct Gadget *) CreateGadget
  259.     (   BUTTON_KIND,
  260.         PrevGadPtr,
  261.         &Gadget,
  262.         GT_Underscore, '_',
  263.         TAG_DONE
  264.     );
  265.  
  266.     // status
  267.     setgadget(446, 20, 72, 12, "Status:", NULL);
  268.     TE101_Status = PrevGadPtr = (struct Gadget *) CreateGadget
  269.     (   TEXT_KIND,
  270.         PrevGadPtr,
  271.         &Gadget,
  272.         GTTX_Text, "Ready",
  273.         GTTX_Border, TRUE,
  274.         TAG_DONE
  275.     );
  276.  
  277.     drawgadgets((UWORD) ~0);
  278.  
  279.     if (wbval < 44)
  280.     {   GT_SetGadgetAttrs
  281.         (   CB99_Log,
  282.             MainWindowPtr, NULL,
  283.             GA_Disabled, TRUE,
  284.             TAG_DONE
  285.         );
  286.     }
  287.     if (!shared.log)
  288.     {   GT_SetGadgetAttrs
  289.         (   ST99_Output,
  290.             MainWindowPtr, NULL,
  291.             GA_Disabled, TRUE,
  292.             TAG_DONE
  293.         );
  294.         GT_SetGadgetAttrs
  295.         (   BU99_OutputASL,
  296.             MainWindowPtr, NULL,
  297.             GA_Disabled, TRUE,
  298.             TAG_DONE
  299.         );
  300.     }
  301.     loop();
  302.     if (ResultNodes)
  303.     {   clearreactionlist(&ResultList);
  304.         ResultNodes = FALSE;
  305.     }
  306.     closewindow();
  307. }
  308.  
  309. MODULE void updatefiles(void)
  310. {   ULONG            i;
  311.  
  312.     /* Gadgets are: BU99_Right ('menu')
  313.                     BU99_Update
  314.                     CB99_Log, ST99_Output, BU99_OutputASL
  315.                     CY101_OSVersion
  316.                     CB101_Show[]
  317.     All are ghosted during operation. Then their ghosting status returns
  318.     to normal (not necessarily unghosted).
  319.  
  320.     Disable the `Menu' (BU), `Update' (BU). `Log to file?' (CB),
  321.     `Pathname' (ST), `...' (BU), `Show' (CB), `OS version' (MX), `Stop'
  322.     (BU) gadgets. Status (TE) is changed.
  323.  
  324.         0: Gadget handling.
  325.         1: Set up lists, do the directory examination.
  326.            (For each `source' directory in the `queue', before doing it
  327.            we check for a break. `Break opportunity 1'.)
  328.     At this point we have an empty DirList, and a full FileList, and an
  329.     empty ResultList.
  330.         2: Create the ResultList.
  331.            (For each `source' file in the `queue', before doing it we
  332.            check for a break. `Break opportunity 2'.)
  333.         3: Show results.
  334.  
  335.        DirList: an Exec list of directories found, awaiting examination.
  336.       FileList: an Exec list of files found, awaiting processing.
  337.     ResultList: a listbrowser list of files found, for display. */
  338.  
  339.     strcpy
  340.     (   shared.output,
  341.         ((struct StringInfo *) ST99_Output->SpecialInfo)->Buffer
  342.     );
  343.  
  344.     stop = FALSE;
  345.     GT_SetGadgetAttrs
  346.     (   BU99_Right,
  347.         MainWindowPtr, NULL,
  348.         GA_Disabled, TRUE,
  349.         TAG_DONE
  350.     );
  351.     GT_SetGadgetAttrs
  352.     (   BU99_Update,
  353.         MainWindowPtr, NULL,
  354.         GA_Disabled, TRUE,
  355.         TAG_DONE
  356.     );
  357.     GT_SetGadgetAttrs
  358.     (   CB99_Log,
  359.         MainWindowPtr, NULL,
  360.         GA_Disabled, TRUE,
  361.         TAG_DONE
  362.     );
  363.     GT_SetGadgetAttrs
  364.     (   ST99_Output,
  365.         MainWindowPtr, NULL,
  366.         GA_Disabled, TRUE,
  367.         TAG_DONE
  368.     );
  369.     GT_SetGadgetAttrs
  370.     (   BU99_OutputASL,
  371.         MainWindowPtr, NULL,
  372.         GA_Disabled, TRUE,
  373.         TAG_DONE
  374.     );
  375.     GT_SetGadgetAttrs
  376.     (   CY101_OSVersion,
  377.         MainWindowPtr, NULL,
  378.         GA_Disabled, TRUE,
  379.         TAG_DONE
  380.     );
  381.     for (i = 0; i <= 7; i++)
  382.     {   GT_SetGadgetAttrs
  383.         (   CB101_Show[i],
  384.             MainWindowPtr, NULL,
  385.             GA_Disabled, TRUE,
  386.             TAG_DONE
  387.         );
  388.     }
  389.     GT_SetGadgetAttrs
  390.     (   BU99_Stop,
  391.         MainWindowPtr, NULL,
  392.         GA_Disabled, FALSE,
  393.         TAG_DONE
  394.     );
  395.     GT_SetGadgetAttrs
  396.     (   TE101_Status,
  397.         MainWindowPtr, NULL,
  398.         GTTX_Text, "Busy",
  399.         TAG_DONE
  400.     );
  401.  
  402.     SetGadgetAttrs
  403.     (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  404.         LISTBROWSER_Labels, NULL,
  405.         TAG_END
  406.     );
  407.     SetGadgetAttrs
  408.     (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  409.         LISTBROWSER_Labels, (ULONG) &EmptyList,
  410.         TAG_END
  411.     );
  412.     if (ResultNodes)
  413.     {   clearreactionlist(&ResultList);
  414.         ResultNodes = FALSE;
  415.     }
  416.  
  417.     stage1();
  418.     if (!stop)
  419.     {   stage2();
  420.     }
  421.     FreeNameNodes(&FileList);
  422.     if (!stop)
  423.     {   stage3();
  424.     }
  425.  
  426.     GT_SetGadgetAttrs
  427.     (   BU99_Right,
  428.         MainWindowPtr, NULL,
  429.         GA_Disabled, FALSE,
  430.         TAG_DONE
  431.     );
  432.     GT_SetGadgetAttrs
  433.     (   BU99_Update,
  434.         MainWindowPtr, NULL,
  435.         GA_Disabled, FALSE,
  436.         TAG_DONE
  437.     );
  438.     if (wbval >= 44)
  439.     {   GT_SetGadgetAttrs
  440.         (   CB99_Log,
  441.             MainWindowPtr, NULL,
  442.             GA_Disabled, FALSE,
  443.             TAG_DONE
  444.         );
  445.     }
  446.     if (shared.log)
  447.     {   GT_SetGadgetAttrs
  448.         (   ST99_Output,
  449.             MainWindowPtr, NULL,
  450.             GA_Disabled, FALSE,
  451.             TAG_DONE
  452.         );
  453.         GT_SetGadgetAttrs
  454.         (   BU99_OutputASL,
  455.             MainWindowPtr, NULL,
  456.             GA_Disabled, FALSE,
  457.             TAG_DONE
  458.         );
  459.     }
  460.     GT_SetGadgetAttrs
  461.     (   CY101_OSVersion,
  462.         MainWindowPtr, NULL,
  463.         GA_Disabled, FALSE,
  464.         TAG_DONE
  465.     );
  466.     for (i = 0; i <= 7; i++)
  467.     {   GT_SetGadgetAttrs
  468.         (   CB101_Show[i],
  469.             MainWindowPtr, NULL,
  470.             GA_Disabled, FALSE,
  471.             TAG_DONE
  472.         );
  473.     }
  474.     GT_SetGadgetAttrs
  475.     (   BU99_Stop,
  476.         MainWindowPtr, NULL,
  477.         GA_Disabled, TRUE,
  478.         TAG_DONE
  479.     );
  480.     GT_SetGadgetAttrs
  481.     (   TE101_Status,
  482.         MainWindowPtr, NULL,
  483.         GTTX_Text, "Ready",
  484.         TAG_DONE
  485.     );
  486. }
  487.  
  488. MODULE void stage1(void)
  489. {   struct NameNode* NodePtr;
  490.  
  491.     NewList(&FileList);
  492.     NewList(&DirList);
  493.     NewList(&ResultList);
  494.     AddNameToTail(&DirList, "");
  495.     // pop all the directories from the work stack, and send them one
  496.     // at a time to files_work() for processing.
  497.     while ((DirList.lh_Head)->ln_Succ) // while the list is non-empty
  498.     {   if (checkbreak() == 1) // we don't yet support completely quitting
  499.         {   stop = TRUE;
  500.             GT_SetGadgetAttrs
  501.             (   TE101_Status,
  502.                 MainWindowPtr, NULL,
  503.                 GTTX_Text, "Stopping",
  504.                 TAG_DONE
  505.             );
  506.             GT_SetGadgetAttrs
  507.             (   BU99_Stop,
  508.                 MainWindowPtr, NULL,
  509.                 GA_Disabled, TRUE,
  510.                 TAG_DONE
  511.             );
  512.             break;
  513.         }
  514.  
  515.         /* remove the dir-node from the list, copy its path to
  516.            stringholder1, call files_work, then free the dir-node. */
  517.  
  518.         if (!(NodePtr = (struct NameNode *) RemTail(&DirList)))
  519.         {   rq("RemTail() failed (list is empty!)"); // this should never happen
  520.         }
  521.         strcpy(stringholder1, NodePtr->nn_Data);
  522.         files_work();
  523.         FreeMem(NodePtr, sizeof(struct NameNode));
  524.     }
  525.     FreeNameNodes(&DirList); // Not required unless stopping early (although harmless).
  526. }
  527.  
  528. MODULE void stage2(void)
  529. {   ABOOL            matched, infomatched;
  530.     ULONG            i, length;
  531.     UBYTE            theversion;
  532.     struct NameNode* NodePtr;
  533.  
  534.     // Everything is already allocated. Don't deallocate in this routine.
  535.  
  536.     if (shared.log)
  537.     {   if (!(LogFileHandle = (BPTR) Open(shared.output, MODE_READWRITE)))
  538.             rq("Can't open file for appending!");
  539.         Seek(LogFileHandle, 0, OFFSET_END);
  540.     }
  541.  
  542.     // Now we have the list of files
  543.     getdate();
  544.     strcpy(IOBuffer, "AmigaOS 3.");
  545.     if (files.osversion == 0)
  546.     {   theversion = 31;
  547.         strcat(IOBuffer, "1");
  548.     } elif (files.osversion == 1)
  549.     {   theversion = 35;
  550.         strcat(IOBuffer, "5");
  551.     } elif (files.osversion == 2)
  552.     {   theversion = 36;
  553.         strcat(IOBuffer, "5 + BB1/2");
  554.     } elif (files.osversion == 3)
  555.     {   theversion = 39;
  556.         strcat(IOBuffer, "9");
  557.     } elif (files.osversion == 5)
  558.     {   theversion = 41;
  559.         strcat(IOBuffer, "9 + BB1");
  560.     } else
  561.     {   // assert(files.osversion == 4);
  562.         theversion = 40;
  563.         strcat(IOBuffer, "9 + Genesis Update");
  564.     }
  565.     strcat(IOBuffer, " system files at ");
  566.     strcat(IOBuffer, timestring);
  567.     strcat(IOBuffer, " on ");
  568.     strcat(IOBuffer, weekdaystring);
  569.     strcat(IOBuffer, " ");
  570.     strcat(IOBuffer, datestring);
  571.     strcat(IOBuffer, ":\n"); // another \n is inserted automatically by dobuffer()
  572.     dobuffer(FALSE, 0);
  573.  
  574.     for (i = 0; i <= FILES; i++)
  575.         os[i].matched = os[i].infomatched = FALSE;
  576.  
  577.     // stop is always FALSE at this point, because this function is not
  578.     // called otherwise.
  579.  
  580.     while ((FileList.lh_Head)->ln_Succ) // while the list is non-empty
  581.     {   if (checkbreak() == 1)
  582.         {   stop = TRUE;
  583.             GT_SetGadgetAttrs
  584.             (   TE101_Status,
  585.                 MainWindowPtr, NULL,
  586.                 GTTX_Text, "Stopping",
  587.                 TAG_DONE
  588.             );
  589.             GT_SetGadgetAttrs
  590.             (   BU99_Stop,
  591.                 MainWindowPtr, NULL,
  592.                 GA_Disabled, TRUE,
  593.                 TAG_DONE
  594.             );
  595.             strcpy(IOBuffer, "Aborted by user!");
  596.             dobuffer(FALSE, 0);
  597.             break;
  598.         }
  599.         // assert(!stop);
  600.  
  601.         if (!(NodePtr = (struct NameNode *) RemTail(&FileList)))
  602.         {   rq("RemTail() failed (list is empty!)"); // should never happen
  603.         }
  604.         strcpy(stringholder1, NodePtr->nn_Data);
  605.         length = strlen(stringholder1);
  606.         FreeMem(NodePtr, sizeof(struct NameNode));
  607.  
  608.         // now we have removed the file from the `queue', and copied its
  609.         // name into stringholder1. Now we check it against each system
  610.         // file.
  611.  
  612.         matched = infomatched = FALSE;
  613.         for (i = 0; i <= FILES; i++)
  614.         {   if (os[i].version <= theversion)
  615.             {   if (!matched && quickcomp(stringholder1, os[i].pathname))
  616.                 {   // we have a match
  617.  
  618.                     strcpy(IOBuffer, os[i].pathname);
  619.                     matched = os[i].matched = TRUE;
  620.  
  621.                     // check whether file is obsoleted by OS3.9 or by Genesis Update
  622.                     if
  623.                     (   (theversion >= 39 && (os[i].flags & NOT39))
  624.                      || (theversion >= 40 && (os[i].flags & NOT39UPDATE))
  625.                      || (os[i].flags & CODE_BLUE)
  626.                     )
  627.                     {   dobuffer(TRUE, 12);
  628.                     } elif (os[i].flags & CODE_RED)
  629.                     {   dobuffer(TRUE,  8);
  630.                     } elif (os[i].flags & CODE_ORANGE)
  631.                     {   dobuffer(TRUE,  9);
  632.                     } elif (os[i].flags & CODE_YELLOW)
  633.                     {   dobuffer(TRUE, 10);
  634.                     } else
  635.                     {   // assert(os[i].flags & CODE_GREEN);
  636.                         dobuffer(TRUE, 11);
  637.                 }   }
  638.                 elif
  639.                 (   !infomatched
  640.                  && (os[i].flags & INFO)
  641.                  && (stringholder1[length - 5] == '.')
  642.                 ) // we probably have a match, let's confirm
  643.                 {   strcpy(IOBuffer, os[i].pathname);
  644.                     strcat(IOBuffer, ".info");
  645.                     if (quickcomp(stringholder1, IOBuffer))
  646.                     {   // we have a match
  647.                         infomatched = os[i].infomatched = TRUE;
  648.  
  649.                         // check whether file is obsoleted by OS3.9 or by Genesis Update
  650.                         if
  651.                         (   (theversion >= 39 && (os[i].flags & NOT39))
  652.                          || (theversion >= 40 && (os[i].flags & NOT39UPDATE))
  653.                         )
  654.                         {   dobuffer(TRUE, 12); // obsolete
  655.                         } else
  656.                         {   dobuffer(TRUE, 11); // automatic .info files are always green
  657.         }   }   }   }   }
  658.         if (!matched && !infomatched) // third-party (cyan)
  659.         {   strcpy(IOBuffer, stringholder1);
  660.             dobuffer(TRUE, 13);
  661.     }   }
  662.  
  663.     // missing files
  664.     if (!stop)
  665.     {   for (i = 0; i <= FILES; i++)
  666.         {   if
  667.             (   !(os[i].flags & CODE_BLUE) // missing obsolete are NEVER shown
  668.              && os[i].version <= theversion
  669.              && (theversion < 39 || !(os[i].flags & NOT39))
  670.              && (theversion < 40 || !(os[i].flags & NOT39UPDATE))
  671.             )
  672.             if (files.show[6] && !(os[i].flags & OPTIONAL))
  673.             {   if (!os[i].matched)
  674.                 {   strcpy(IOBuffer, os[i].pathname); // white (missing normal)
  675.                     dobuffer(TRUE, 14);
  676.                 }
  677.                 if ((os[i].flags & INFO) && !os[i].infomatched)
  678.                 {   strcpy(IOBuffer, os[i].pathname); // white (missing normal)
  679.                     strcat(IOBuffer, ".info");
  680.                     dobuffer(TRUE, 14);
  681.             }   }
  682.             elif (files.show[7] &&  (os[i].flags & OPTIONAL))
  683.             {   if (!os[i].matched)
  684.                 {   strcpy(IOBuffer, os[i].pathname); // pink (missing optional)
  685.                     dobuffer(TRUE, 15);
  686.                 }
  687.                 if ((os[i].flags & INFO) && !os[i].infomatched)
  688.                 {   strcpy(IOBuffer, os[i].pathname); // pink (missing optional)
  689.                     strcat(IOBuffer, ".info");
  690.                     dobuffer(TRUE, 15);
  691.     }   }   }   }
  692.  
  693.     if (LogFileHandle)
  694.     {   Close(LogFileHandle); // Close() doesn't return an error code
  695.         LogFileHandle = NULL;
  696. }   }
  697.  
  698. MODULE void stage3(void)
  699. {   if (wbval >= 44)
  700.     {   /* pens go thusly:
  701.         0 red
  702.         1 orange
  703.         2 yellow
  704.         3 green
  705.         4 blue
  706.         5 cyan
  707.         6 white
  708.         7 pink */
  709.  
  710.         GT_SetGadgetAttrs
  711.         (   TE101_Status,
  712.             MainWindowPtr, NULL,
  713.             GTTX_Text, "Ready",
  714.             TAG_DONE
  715.         );
  716.         GT_SetGadgetAttrs
  717.         (   BU99_Stop,
  718.             MainWindowPtr, NULL,
  719.             GA_Disabled, TRUE,
  720.             TAG_DONE
  721.         );
  722.  
  723.         SetGadgetAttrs
  724.         (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  725.             LISTBROWSER_Labels, NULL,
  726.             TAG_END
  727.         );
  728.         SetGadgetAttrs
  729.         (   gadgets[GID_10_LB1], MainWindowPtr, NULL,
  730.             LISTBROWSER_Labels, (ULONG) &ResultList,
  731.             TAG_END
  732.         );
  733. }   }
  734.  
  735. /* FileNamePtr[]: each of these is a pointer to the allocated memory
  736. area holding the pathname of that file found (excepting "SYS:" portion).
  737. FileNamesAllocated = number of elements of FileNamePtr[]. Or, another way
  738. to think of it, the number of files on the SYS: partition. Element 0 of
  739. the array is not used. */
  740.  
  741. MODULE void files_work(void)
  742. {   BOOL                 more; // BOOL, not ABOOL
  743.     BPTR                 DirHandle; // = NULL;
  744.     struct ExAllControl* eac;       // = NULL;
  745.     struct ExAllData*    ead;
  746.  
  747.     /* Service routine for stage1(). Each call of this routine
  748.     handles one directory from the work stack. This routine is the one
  749.     that actually makes the DOS calls. It pushes any subdirectories
  750.     found onto the stack.
  751.  
  752.     stringholder1 contains the pathname of the directory to examine
  753.         (without "SYS:").
  754.     lockstring contains the pathname of the directory to examine
  755.         (with "SYS:").
  756.     stringholder2 will contain the pathname of each file/dir found
  757.         (with "SYS:"). */
  758.  
  759.     strcpy(lockstring, "SYS:");
  760.     strcat(lockstring, stringholder1);
  761.  
  762.     if (!(DirHandle = (BPTR) Lock(lockstring, ACCESS_READ)))
  763.     {   // Printf("Can't lock %s!\n", lockstring);
  764.         rq("Can't lock directory!");
  765.     }
  766.     if (!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
  767.     {   UnLock(DirHandle);
  768.         DirHandle = NULL;
  769.         rq("Can't allocate DOS object!");
  770.     }
  771.  
  772.     eac->eac_LastKey = 0;
  773.     do
  774.     {   more = ExAll(DirHandle, (struct ExAllData *) EADataPtr, 2048, ED_SIZE, eac);
  775.         if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
  776.         {   FreeDosObject(DOS_EXALLCONTROL, eac);
  777.             eac = NULL;
  778.             UnLock(DirHandle);
  779.             DirHandle = NULL;
  780.             rq("Can't examine path!"); /* ExAll() failed abnormally */
  781.         }
  782.         if (eac->eac_Entries == 0)
  783.         {   ; /* ExAll() failed normally with no entries */
  784.             continue; /* more is USUALLY zero */
  785.         }
  786.         ead = (struct ExAllData *) EADataPtr;
  787.  
  788.         do
  789.         {   /* use ead here */
  790.  
  791.             strcpy(stringholder2, lockstring);
  792.             if (!AddPart(stringholder2, ead->ed_Name, VLONGFIELD))
  793.             {   FreeDosObject(DOS_EXALLCONTROL, eac);
  794.                 eac = NULL;
  795.                 UnLock(DirHandle);
  796.                 DirHandle = NULL;
  797.                 rq("Can't add filename/dirname to pathname!");
  798.             }
  799.             if (ead->ed_Type == 2) /* +2 is dir, +3 is softlink, -3 is file */
  800.             {   AddNameToTail(&DirList,  &(stringholder2[4]));
  801.             } elif (ead->ed_Type == -3) // if it's a file
  802.             {   AddNameToTail(&FileList, &(stringholder2[4]));
  803.             }
  804.  
  805.             /* get next ead */
  806.             ead = ead->ed_Next;
  807.         } while(ead);
  808.     } while(more);
  809.  
  810.     FreeDosObject(DOS_EXALLCONTROL, eac);
  811.     eac = NULL;
  812.     UnLock(DirHandle);
  813.     DirHandle = NULL;
  814. }
  815.  
  816. MODULE ABOOL __inline quickcomp(STRPTR first, STRPTR second)
  817. {   ULONG i = 0;
  818.  
  819.     while (*(first + i))
  820.     {   if (*(first + i)      != *(second + i)
  821.         &&  *(first + i)      != *(second + i) + 32
  822.         &&  *(first + i) + 32 != *(second + i)
  823.         &&  *(first + i) + 32 != *(second + i) + 32
  824.         )
  825.             return FALSE;
  826.         i++;
  827.     }
  828.     return TRUE;
  829. }
  830.  
  831. MODULE void dobuffer(ABOOL item, ULONG whichpen)
  832. {   struct Node* ListBrowserNodePtr;
  833.     TEXT         codestring[VLONGFIELD + 1];
  834.  
  835.     /* Service routine for stage2(). */
  836.  
  837.     if (item && files.show[whichpen - 8])
  838.     {   if (!(ListBrowserNodePtr = AllocListBrowserNode
  839.         (   1,              // columns,
  840.             LBNA_Column,    0,
  841.             LBNA_Flags,     LBFLG_CUSTOMPENS,
  842.             LBNCA_FGPen,    BLACK,
  843.             LBNCA_BGPen,    penn[whichpen - 8].pennumber,
  844.             LBNCA_CopyText, TRUE,
  845.             LBNCA_Text,     IOBuffer,
  846.             TAG_END))
  847.         )
  848.         {   rq("Can't create ReAction listbrowser.gadget node(s)!");
  849.         }
  850.         AddTail(&ResultList, ListBrowserNodePtr); // AddTail() has no return code
  851.         ResultNodes = TRUE;
  852.     }
  853.     if (shared.log)
  854.     {   if (!item)
  855.         {   strcpy(codestring, IOBuffer);
  856.             strcat(codestring, "\n");
  857.             if (Write(LogFileHandle, codestring, strlen(codestring)) == -1)
  858.             {   rq("Can't append to file!");
  859.         }   }
  860.         elif (files.show[whichpen - 8])
  861.         {   switch(whichpen)
  862.             {
  863.             case 8:
  864.                 strcpy(codestring, "! "); // red
  865.             break;
  866.             case 9:
  867.                 strcpy(codestring, "@ "); // orange
  868.             break;
  869.             case 10:
  870.                 strcpy(codestring, "# "); // yellow
  871.             break;
  872.             case 11:
  873.                 strcpy(codestring, "$ "); // green
  874.             break;
  875.             case 12:
  876.                 strcpy(codestring, "% "); // blue (obsolete)
  877.             break;
  878.             case 13:
  879.                 strcpy(codestring, "& "); // cyan (3rd-party)
  880.             break;
  881.             case 14:
  882.                 strcpy(codestring, "- "); // white (missing normal)
  883.             break;
  884.             case 15:
  885.                 strcpy(codestring, "= "); // pink (missing optional)
  886.             break;
  887.             default:
  888.                 // assert(0);
  889.             break;
  890.             }
  891.             strcat(codestring, IOBuffer);
  892.             strcat(codestring, "\n");
  893.             if (Write(LogFileHandle, codestring, strlen(codestring)) == -1)
  894.             {   rq("Can't append to file!");
  895. }   }   }   }
  896.  
  897. AGLOBAL void files_loop(ULONG class, struct Gadget* addr, UWORD code, UWORD qual)
  898. {   ULONG i, scroll;
  899.  
  900.     if (class == IDCMP_RAWKEY && wbval >= 44)
  901.     {   if (code == SCAN_UP)
  902.         {   if (qual & IEQUALIFIER_CONTROL)
  903.             {   scroll = LBP_TOP;
  904.             } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  905.             {   scroll = LBP_PAGEUP;
  906.             } else scroll = LBP_LINEUP;
  907.         } elif (code == SCAN_DOWN)
  908.         {   if (qual & IEQUALIFIER_CONTROL)
  909.             {   scroll = LBP_BOTTOM;
  910.             } elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
  911.             {   scroll = LBP_PAGEDOWN;
  912.             } else scroll = LBP_LINEDOWN;
  913.         }
  914.         if (code == SCAN_UP || code == SCAN_DOWN)
  915.         {   SetGadgetAttrs
  916.             (   gadgets[GID_10_LB1],          // pointer to gadget
  917.                 MainWindowPtr,                // pointer to window (not window object!)
  918.                 NULL,                         // pointer to requester
  919.                 LISTBROWSER_Position, scroll, // tags
  920.                 TAG_DONE                      // done
  921.             );
  922.     }   }
  923.     elif (class == IDCMP_VANILLAKEY)
  924.     {   code = toupper(code);
  925.         if (code == 'V')
  926.         {   if (!(qual & IEQUALIFIER_LSHIFT) && !(qual & IEQUALIFIER_RSHIFT))
  927.             {   if (files.osversion < OSVERSIONS)
  928.                     files.osversion++;
  929.                 else files.osversion = 0;
  930.             } else
  931.             {   if (files.osversion > 0)
  932.                     files.osversion--;
  933.                 else files.osversion = OSVERSIONS;
  934.             }
  935.             GT_SetGadgetAttrs
  936.             (   CY101_OSVersion,
  937.                 MainWindowPtr,
  938.                 NULL,
  939.                 GTCY_Active, files.osversion,
  940.                 TAG_DONE
  941.             );
  942.         } elif (code == 'L')
  943.         {   fliplog(TRUE);
  944.         } elif (code == 'U')
  945.         {   updatefiles();
  946.         } elif (code == 'E')
  947.         {   if (CB101_Show[0]->Flags & GFLG_SELECTED)
  948.                 files.show[0] = FALSE;
  949.             else files.show[0] = TRUE;
  950.             GT_SetGadgetAttrs
  951.             (   CB101_Show[0],
  952.                 MainWindowPtr, NULL,
  953.                 GTCB_Checked, files.show[0],
  954.                 TAG_DONE
  955.             );
  956.         } elif (code == 'I')
  957.         {   if (CB101_Show[1]->Flags & GFLG_SELECTED)
  958.                 files.show[1] = FALSE;
  959.             else files.show[1] = TRUE;
  960.             GT_SetGadgetAttrs
  961.             (   CB101_Show[1],
  962.                 MainWindowPtr, NULL,
  963.                 GTCB_Checked, files.show[1],
  964.                 TAG_DONE
  965.             );
  966.         } elif (code == 'S')
  967.         {   if (CB101_Show[2]->Flags & GFLG_SELECTED)
  968.                 files.show[2] = FALSE;
  969.             else files.show[2] = TRUE;
  970.             GT_SetGadgetAttrs
  971.             (   CB101_Show[2],
  972.                 MainWindowPtr, NULL,
  973.                 GTCB_Checked, files.show[2],
  974.                 TAG_DONE
  975.             );
  976.         } elif (code == 'N')
  977.         {   if (CB101_Show[3]->Flags & GFLG_SELECTED)
  978.                 files.show[3] = FALSE;
  979.             else files.show[3] = TRUE;
  980.             GT_SetGadgetAttrs
  981.             (   CB101_Show[3],
  982.                 MainWindowPtr, NULL,
  983.                 GTCB_Checked, files.show[3],
  984.                 TAG_DONE
  985.             );
  986.         } elif (code == 'B')
  987.         {   if (CB101_Show[4]->Flags & GFLG_SELECTED)
  988.                 files.show[4] = FALSE;
  989.             else files.show[4] = TRUE;
  990.             GT_SetGadgetAttrs
  991.             (   CB101_Show[4],
  992.                 MainWindowPtr, NULL,
  993.                 GTCB_Checked, files.show[4],
  994.                 TAG_DONE
  995.             );
  996.         } elif (code == '3')
  997.         {   if (CB101_Show[5]->Flags & GFLG_SELECTED)
  998.                 files.show[5] = FALSE;
  999.             else files.show[5] = TRUE;
  1000.             GT_SetGadgetAttrs
  1001.             (   CB101_Show[5],
  1002.                 MainWindowPtr, NULL,
  1003.                 GTCB_Checked, files.show[5],
  1004.                 TAG_DONE
  1005.             );
  1006.         } elif (code == 'G')
  1007.         {   if (CB101_Show[6]->Flags & GFLG_SELECTED)
  1008.                 files.show[6] = FALSE;
  1009.             else files.show[6] = TRUE;
  1010.             GT_SetGadgetAttrs
  1011.             (   CB101_Show[6],
  1012.                 MainWindowPtr, NULL,
  1013.                 GTCB_Checked, files.show[6],
  1014.                 TAG_DONE
  1015.             );
  1016.         } elif (code == 'P')
  1017.         {   if (CB101_Show[7]->Flags & GFLG_SELECTED)
  1018.                 files.show[7] = FALSE;
  1019.             else files.show[7] = TRUE;
  1020.             GT_SetGadgetAttrs
  1021.             (   CB101_Show[7],
  1022.                 MainWindowPtr, NULL,
  1023.                 GTCB_Checked, files.show[7],
  1024.                 TAG_DONE
  1025.             );
  1026.         } elif (code == 'O')
  1027.         {   ActivateGadget(ST99_Output, MainWindowPtr, NULL);
  1028.         } elif (code == '.')
  1029.         {   if (asl())
  1030.             {   GT_SetGadgetAttrs
  1031.                 (   ST99_Output,
  1032.                     MainWindowPtr,
  1033.                     NULL,
  1034.                     GTST_String, aslresult,
  1035.                     TAG_DONE
  1036.                 );
  1037.         }   }
  1038.         elif (code == ESCAPE)
  1039.         {   page = 0;
  1040.     }   }
  1041.     elif (class == IDCMP_GADGETUP)
  1042.     {   /* IDCMP_GADGETUP is sent by the string gadget
  1043.            when the user presses RETURN, ENTER, Help, Tab
  1044.            or Shift-Tab inside the string gadget. */
  1045.  
  1046.         if (addr == BU99_Right)
  1047.         {   page = 0;
  1048.         } elif (addr == BU99_Update)
  1049.         {   updatefiles();
  1050.         } elif (addr == CB99_Log)
  1051.         {   fliplog(FALSE);
  1052.         } elif (addr == ST99_Output)
  1053.         {   outputstring();
  1054.         } elif (addr == BU99_OutputASL)
  1055.         {   outputasl();
  1056.         } elif (addr == CY101_OSVersion)
  1057.         {   files.osversion = code;
  1058.         } else
  1059.         {   for (i = 0; i <= 6; i++)
  1060.             {   if (addr == CB101_Show[i])
  1061.                 {   if (CB101_Show[i]->Flags & GFLG_SELECTED)
  1062.                     {   files.show[i] = TRUE;
  1063.                     } else files.show[i] = FALSE;
  1064.                     GT_SetGadgetAttrs
  1065.                     (   CB101_Show[i],
  1066.                         MainWindowPtr, NULL,
  1067.                         GTCB_Checked, files.show[i],
  1068.                         TAG_DONE
  1069.                     );
  1070.                     break;
  1071. }   }   }   }   }
  1072.  
  1073. AGLOBAL void files_init(void)
  1074. {   ULONG i;
  1075.  
  1076.     if (wbval == 44)
  1077.     {   files.osversion = 2;  // OS3.5 + BB1/2
  1078.     } else files.osversion = 5; // OS3.9 + BB1
  1079.  
  1080.     lockscreen();
  1081.     for (i = 0; i <= 7; i++)
  1082.     {   penn[i].pennumber = FindColor
  1083.         (   ScreenPtr->ViewPort.ColorMap,
  1084.             penn[i].red,
  1085.             penn[i].green,
  1086.             penn[i].blue,
  1087.             -1
  1088.         );
  1089.     }
  1090.     unlockscreen();
  1091. }
  1092.  
  1093. AGLOBAL void files_exit(void)
  1094. {   // The window should be closed before calling this.
  1095.  
  1096.     if (ResultNodes)
  1097.     {   clearreactionlist(&ResultList);
  1098.         ResultNodes = FALSE;
  1099.     }
  1100.     if (LogFileHandle)
  1101.     {   Close(LogFileHandle); // Close() doesn't return an error code
  1102.         LogFileHandle = NULL;
  1103. }   }
  1104.  
  1105. AGLOBAL void files_die(void)
  1106. {   ULONG i;
  1107.  
  1108.     IOBuffer[7] = files.osversion;
  1109.  
  1110.     for (i = 0; i <= 7; i++)
  1111.     {   IOBuffer[8 + i] = files.show[i];
  1112. }   }
  1113.  
  1114. AGLOBAL void files_config(void)
  1115. {   ULONG i;
  1116.  
  1117.     files.osversion = IOBuffer[7];
  1118.  
  1119.     for (i = 0; i <= 7; i++)
  1120.     {   files.show[i] = IOBuffer[8 + i];
  1121. }   }
  1122.